package com.intexh.speedandroid.widget.tag;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 标签容器
 * 限制一行个数3 个 应该写成自定义参数 待优化
 */
public class FlowLayout extends ViewGroup implements View.OnClickListener {

    private int parentMeasuredWidth;
    private String flowLayoutTag;   //flowLayout 的身份标识
    private OnTagMultiSelectListener onTagMultiSelectListener;
    private int lineTagCount;   //一行显示的tag数


    public enum TagGravity {
        LEFT, CENTER, RIGHT
    }
    public enum TagSelectModel {
        RADIO_SELECT_MODEL, MULTI_SELECT_MODEL
    }

    /**
     * 多行View
     */
    private ArrayList<ArrayList<View>> multiLines = new ArrayList<>();
    private int horizontalSpacing = 10;
    private int verticalSpacing = 10;
    private TagGravity tagGravity = TagGravity.LEFT;
    private TagSelectModel tagSelectModel = TagSelectModel.MULTI_SELECT_MODEL;  //默认为多选模式
    private boolean tagAverageLine = false;
    private OnTagRadioSelectListener onTagRadioSelectListener;
    private int selectedTextColor; //单选模式 选中的颜色
    private Drawable selectedBackground; //单选模式选中背景颜色
    private int defaultTextColor; //标签设置的字体颜色
    private Drawable defaultBackground=null; //标签设置的背景
    private float defaultTextSize;  //标签设置的字体大小
    private int last_select_id = -1; //单选模式上次一选择的id

    private Map<String,String> selectTagMap = new HashMap<>(); //多选下选中的tag

    ArrayList<View> oneLineViews = null;    // 一行View
    private List<TagTextView> tags;


    public void setLast_select_id(int last_select_id) {
        this.last_select_id = last_select_id;
    }

    public FlowLayout(Context context) {
        this(context,null);
    }

    public FlowLayout(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 测量FlowLayout及它的子View
     *
     * @param widthMeasureSpec  父容器希望FlowLayout的宽
     * @param heightMeasureSpec 父容器希望FlowLayout的高
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        multiLines.clear();
        // 获取FlowLayout测量的宽
        parentMeasuredWidth = MeasureSpec.getSize(widthMeasureSpec);
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            // 把测量规格传给子View，让子View完成测量
            child.measure(MeasureSpec.makeMeasureSpec(parentMeasuredWidth, MeasureSpec.AT_MOST), 0);

            int childMeasuredWidth = child.getMeasuredWidth();

            // 如果是第0个需要创建新行，或者当前View的宽度大于一行中剩余的可用宽度也需要创建新行
            if (i == 0 || childMeasuredWidth > parentMeasuredWidth
                    - getPaddingLeft()
                    - getPaddingRight()
                    - getLineWidth(oneLineViews)) {
                oneLineViews = new ArrayList<>();
                multiLines.add(oneLineViews);
            }
//            if(lineTagCount==-1){
//                if (i == 0 || childMeasuredWidth > parentMeasuredWidth
//                        - getPaddingLeft()
//                        - getPaddingRight()
//                        - getLineWidth(oneLineViews)) {
//                    oneLineViews = new ArrayList<>();
//                    multiLines.add(oneLineViews);
//                }
//            }else{
//                if (i == 0 || childMeasuredWidth > parentMeasuredWidth
//                        - getPaddingLeft()
//                        - getPaddingRight()
//                        - getLineWidth(oneLineViews) ||i%lineTagCount==0) {
//                    oneLineViews = new ArrayList<>();
//                    multiLines.add(oneLineViews);
//                }
//            }
            oneLineViews.add(child);
        }

        // 设置FlowLayout的宽和高，宽就用父容器传的宽，高用所有行的高
        setMeasuredDimension(parentMeasuredWidth, getAllLineHeight() + getPaddingTop() + getPaddingBottom());
    }


    /**
     * 获取所有行的高 包含设置的paddingTop 与 paddingBottom 和所有行距
     */
    public int getAllLineHeight() {
        if (multiLines.size() <= 0) {
            return 0;
        } else {
            int totalSpacing = (multiLines.size() - 1) * verticalSpacing;
            return multiLines.get(0).get(0).getMeasuredHeight() * multiLines.size() + totalSpacing;
        }
    }




    /**
     * 获取行宽
     */
    private int getLineWidth(ArrayList<View> views) {
        int lineWidth = 0;
        for (int i = 0; i < views.size(); i++) {
            lineWidth = lineWidth + views.get(i).getMeasuredWidth();
        }
        int totalSpacing = (views.size() - 1) * horizontalSpacing;
        return lineWidth + totalSpacing;
    }

    /**
     * 对FlowLayout的子View进行排版
     *
     * @param parentLeft   FlowLayout的left坐标
     * @param parentTop    FlowLayout的top坐标
     * @param parentRight  FlowLayout的right坐标
     * @param parentBottom FlowLayout的bottom坐标
     */
    @Override
    protected void onLayout(boolean changed, int parentLeft, int parentTop, int parentRight, int parentBottom) {
        int preLineBottom = 0;
        for (int i = 0; i < multiLines.size(); i++) {
            ArrayList<View> oneLineViews = multiLines.get(i);

            // 一行中可用的宽（没有被使用的宽）
            int usableWidth = getMeasuredWidth() - getPaddingLeft()
                    - getPaddingRight()
                    - getLineWidth(oneLineViews);

            // 平均每个View可多分到的宽
            int averageUsableWidth = usableWidth / oneLineViews.size();

            int columOnePaddingLeft = 0;
            if (usableWidth > 0) {
                columOnePaddingLeft = usableWidth / 2; //一行中可用宽的一半，用于设置标签居中
            }
            int preColumnRight = 0;
            for (int j = 0; j < oneLineViews.size(); j++) {
                View column = oneLineViews.get(j);

                // 获取子View的宽和高
                int childWidth = column.getMeasuredWidth();
                int childHeight = column.getMeasuredHeight();

                // 设置子View在容器中的位置
                int childLeft = 0;
                if (j == 0) {
                    // 如果是第一列，则它的left位置要加上paddingLeft
                    if(tagAverageLine){
                        childLeft = parentLeft + getPaddingLeft() + preColumnRight;
                    }else{
                        switch (tagGravity) {
                            case LEFT:
                                childLeft = parentLeft + getPaddingLeft() + preColumnRight;
                                break;
                            case CENTER:
                                childLeft = parentLeft + getPaddingLeft() + preColumnRight + columOnePaddingLeft;
                                break;
                            case RIGHT:
                                childLeft = parentLeft + getPaddingLeft() + preColumnRight + usableWidth;
                                break;
                        }
                    }

                } else {
                    // 如果不是第一列，则它的left需要加上spacing
                    childLeft = parentLeft + preColumnRight + horizontalSpacing;    // 显示到上一列右边的位置
                }

                int childTop;
                if (i == 0) {
                    // 如果是第一行，则它的top位置要加上paddingTop
                    childTop = parentTop + getPaddingTop() + preLineBottom;
                } else {
                    // 如果不是第一行，则它的top位置要加上spacing
                    childTop = parentTop + preLineBottom + verticalSpacing;    // 显示到上一行下方的位置
                }
                int childRight;
                if (tagAverageLine) {
                    childRight = childLeft + childWidth + averageUsableWidth;
                } else {
                    childRight = childLeft + childWidth;
                }
                int childBottom = childTop + childHeight;
                column.layout(childLeft, childTop, childRight, childBottom);

                // view的宽高改变了，需要重新测量。如果不重新测量的话宽度显示是没有问题的，但是文本内容水平方向不会居中
                int widthMeasureSpec = MeasureSpec.makeMeasureSpec(childRight - childLeft, MeasureSpec.EXACTLY);
                int heightMeasureSpec = MeasureSpec.makeMeasureSpec(childBottom - childTop, MeasureSpec.EXACTLY);
                column.measure(widthMeasureSpec, heightMeasureSpec);

                // 保存当前列的right坐标，用于下次使用
                preColumnRight = childRight;
            }

            // 保存当行行的bottom坐标，用于下次使用
            preLineBottom = oneLineViews.get(0).getBottom();


        }
    }

    /**
     * todo zjw tag初始化太乱 待优化
     */

    /**
     * 设置选择模式与颜色
     * @param tagSelectModel
     * @param selectedTextColor
     * @param selectedBackgroundRes
     */
    public void setTagSelectModel(TagSelectModel tagSelectModel,int selectedTextColor,int selectedBackgroundRes) {
        this.tagSelectModel = tagSelectModel;
        this.selectedTextColor = selectedTextColor;
        this.selectedBackground = ContextCompat.getDrawable(getContext(),selectedBackgroundRes);
    }

    public void setTagSelectModel(TagSelectModel tagSelectModel,
                                  int selectedTextColor,Drawable selectedBackground,
                                  int defaultTextColor,Drawable defaultBackground) {
        this.tagSelectModel = tagSelectModel;
        this.selectedTextColor = selectedTextColor;
        this.selectedBackground = selectedBackground;
        this.defaultTextColor = defaultTextColor;
        this.defaultBackground = defaultBackground;
    }

    /**
     * 设置tag选中后的样式
     * @param selectedTextColor
     * @param selectedBackground
     */
    public void setTagSelectStyle(int selectedTextColor,Drawable selectedBackground) {
        this.selectedTextColor = selectedTextColor;
        this.selectedBackground = selectedBackground;
    }

    /**
     * 设置tag布局的标识 点击回调方法中返回
     * @param flowLayoutTag
     */
    public void setFlowLayoutTag(String flowLayoutTag){
        this.flowLayoutTag = flowLayoutTag;
    }

    public int getHorizontalSpacing() {
        return horizontalSpacing;
    }

    public void setHorizontalSpacing(int horizontalSpacing) {
        this.horizontalSpacing = horizontalSpacing;
    }

    public int getVerticalSpacing() {
        return verticalSpacing;
    }

    public void setVerticalSpacing(int verticalSpacing) {
        this.verticalSpacing = verticalSpacing;
    }

    public TagGravity getTagGravity() {
        return tagGravity;
    }

    /**
     * 设置居中方式 left center right
     * @param tagGravity
     */
    public void setTagGravity(TagGravity tagGravity) {
        this.tagGravity = tagGravity;
    }


    /**
     * tag 平均分布
     * @param tagAverageLine
     */
    public void setTagAverageLine(boolean tagAverageLine) {
        this.tagAverageLine = tagAverageLine;
    }

    public void setDatas(List<TagTextView> datas) {
        if(datas==null&& datas.size()<=0){
            return;
        }
        tags = datas;
        this.removeAllViews();
//        if(last_select_id ==-1){
//            last_select_id = -1;
//        }
        TagTextView t1 = datas.get(0);
        if(defaultTextColor==0){
            defaultTextColor = t1.getTextColors().getColorForState(getDrawableState(), 0);
        }
        if(defaultBackground==null){
            defaultBackground = t1.getBackground();
        }
        defaultTextSize = t1.getTextSize();
        for (int i=0;i<datas.size();i++) {
            TagTextView textView = datas.get(i);
            textView.setId(i);
            textView.setMaxLines(1);
            textView.setOnClickListener(this);
            this.addView(textView);
        }
    }


    /**
     * 设置单选模式下的选择监听
     * @param onTagRadioSelectListener
     */
    public void setOnTagRadioSelectListener(OnTagRadioSelectListener onTagRadioSelectListener) {
        this.onTagRadioSelectListener = onTagRadioSelectListener;
    }

    /**
     * 单选模式的监听器
     */
    public interface OnTagRadioSelectListener {
        /**
         *
         * @param flowLayoutTag   flowLayout 标识
         * @param tagKey   选中的tagView 对应的key
         * @param tagValue   选中的tagView 对应的value
         * @param tagView   选中的tagView
         */
        void onTagSelected(String flowLayoutTag, String tagKey, String tagValue, TagTextView tagView);
    }

    /**
     * 设置多选模式下的选择监听
     * @param onTagMultiSelectListener
     */
    public void setOnTagMultiSelectListener(OnTagMultiSelectListener onTagMultiSelectListener) {
        this.onTagMultiSelectListener = onTagMultiSelectListener;
    }

    /**
     * 多选模式的监听器
     */
    public interface OnTagMultiSelectListener {
        /**
         *
         * @param flowLayoutTag   flowLayout 标识
         * @param selectIds   选中的tags id集合
         * @param currentClickTagView   当前点击的tagView
         */
        void onTagSelected(String flowLayoutTag, Map<String, String> selectIds, TagTextView currentClickTagView);
    }

    @Override
    public void onClick(View view) {
        if(tagSelectModel== TagSelectModel.RADIO_SELECT_MODEL){
            //单选模式处理
            if (onTagRadioSelectListener != null) {
                if(last_select_id ==-1){
                    changeTextViewStyle(view);
                    last_select_id = view.getId();
                }else{
                    if(view.getId() != last_select_id){//改变颜色
                        changeTextViewStyle(view);
                        //还原上一个改变的颜色
                        TagTextView lastSelectView = (TagTextView) getChildAt(last_select_id);
                        lastSelectView.setTextColor(defaultTextColor);
                        lastSelectView.setBackground(defaultBackground);
                        last_select_id = view.getId();
                    }else{
                        return;
                    }
                }
                TagTextView selectTagTextView = (TagTextView) view;
                onTagRadioSelectListener.onTagSelected(flowLayoutTag,selectTagTextView.getKey(),selectTagTextView.getValue(),selectTagTextView);
            }

        }else{
            //多选模式下处理
            if (onTagMultiSelectListener != null) {
                clickTag((TagTextView) view);
                onTagMultiSelectListener.onTagSelected(flowLayoutTag,selectTagMap,(TagTextView) view);
            }

        }

    }



    private void clickTag(TagTextView tagView) {
        if(selectTagMap.containsKey(tagView.getKey())){
            selectTagMap.remove(tagView.getKey());
            tagView.setTextColor(defaultTextColor);
            tagView.setBackground(defaultBackground);
        }else{
            selectTagMap.put(tagView.getKey(),tagView.getKey());
            tagView.setBackground(selectedBackground);
            tagView.setTextColor(selectedTextColor);
        }
    }

    //重置选择状态
/*    public void resetTag(){
        if(getChildCount()>0){
            for(int i=0;i<getChildCount();i++){
                TagTextView tagTextView = (TagTextView) getChildAt(i);
                tagTextView.setTextColor(defaultTextColor);
                tagTextView.setBackground(defaultBackground);
            }
        }
    }*/

    private void changeTextViewStyle(View view) {
        TagTextView tv = (TagTextView) view;
        tv.setBackground(selectedBackground);
        tv.setTextColor(selectedTextColor);
        tv.setMaxLines(1);

    }

    public int dp2px(Context context, float dp)
    {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f); //Then addCity 0.5f to round the figure up to the nearest whole number, when converting to an integer
    }
}
